package com.ihr360.payroll.model.dto.salary.tax;


import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;
import com.ihr360.commons.model.IEnabledEntity;
import com.ihr360.commons.model.type.TaxRole;
import com.ihr360.payroll.model.dto.salary.basecode.SalaryTaxType;
import com.ihr360.payroll.model.dto.salary.basecode.TaxDivision;
import com.ihr360.payroll.model.vo.SalaryTaxTypeVO;
import com.ihr360.payroll.model.vo.SalaryTaxVO;
import com.ihr360.payroll.model.vo.TaxDivisionVO;
import com.ihr360.shared.entitywithlistener.NumberIdWithTime;
import org.apache.commons.collections.CollectionUtils;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 税率表
 */
@Entity
public class SalaryTaxTable extends NumberIdWithTime<Long> implements IEnabledEntity {
    // TODO: 服务走gateway之后，采用 NumberIdWithTime

    private static final long serialVersionUID = 165782898692506575L;

    /**
     * 编码
     */
    @Column(length = 32, unique = true, nullable = false)
    private String code;

    /**
     * 缴税地区
     */
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(nullable = false)
    private TaxDivision division;

    /**
     * 缴税类型
     */
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(nullable = false)
    private SalaryTaxType type;

    /**
     * 状态
     */
    @Column(nullable = false)
    private Boolean enabled = true;

    /**
     * 代扣/代付
     */
    @Column(nullable = false)
    private Boolean affordByStaff = true;

    /**
     * 纳税身份
     */
    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private TaxRole taxRole = TaxRole.NATIVE;

    /**
     * 个税配置
     */
    @OneToMany(mappedBy = "taxTable", cascade = CascadeType.ALL, orphanRemoval = true)
    @OrderBy("effectiveAt desc")
    private List<SalaryTax> salaryTaxes = Lists.newArrayList();


    @Column(length = 1000)
    private String remark;

    @Column(columnDefinition = "bit(1) default 0")
    private boolean embedded;

    public TaxDivision getDivision() {
        return division;
    }

    public void setDivision(TaxDivision division) {
        this.division = division;
    }

    public SalaryTaxType getType() {
        return type;
    }

    public void setType(SalaryTaxType type) {
        this.type = type;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public boolean isAffordByStaff() {
        return affordByStaff;
    }

    public void setAffordByStaff(boolean affordByStaff) {
        this.affordByStaff = affordByStaff;
    }

    public TaxRole getTaxRole() {
        return taxRole;
    }

    public void setTaxRole(TaxRole taxRole) {
        this.taxRole = taxRole;
    }


    public List<SalaryTax> getSalaryTaxes() {
        return salaryTaxes;
    }

    public void setSalaryTaxes(List<SalaryTax> salaryTaxes) {
        this.salaryTaxes = salaryTaxes;
    }

    @Override
    public boolean isEnabled() {
        return this.enabled;
    }

    @Override
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }


    @JsonIgnore
    public TaxDivisionVO getTaxDivisionVO() {
        if (division == null) {
            return null;
        }
        return new TaxDivisionVO(division.getId(), division.getCode(), division.getName());
    }

    @JsonIgnore
    public SalaryTaxTypeVO getSalaryTaxTypeVO() {
        if (type == null) {
            return null;
        }
        return new SalaryTaxTypeVO(type.getId(), type.getCode(), type.getName());
    }

    @JsonIgnore
    public List<SalaryTaxVO> getSalaryTaxVOs() {
        if (CollectionUtils.isEmpty(salaryTaxes)) {
            return Collections.emptyList();
        }
        ArrayList<SalaryTaxVO> results = Lists.newArrayListWithCapacity(salaryTaxes.size());
        salaryTaxes.forEach(salaryTax ->
                results.add(new SalaryTaxVO(salaryTax.getId(), salaryTax.getEffectiveAt(), salaryTax.getInvalidAt(), salaryTax.isFixed(), salaryTax.getRuleVOs())));
        return results;
    }

}
